//
// Created by scl on 2024/4/5.
//
#include "streaming.grpc.pb.h"
#include <grpc++/grpc++.h>
#include <iostream>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using example::Point;
using example::PointCloud;
using example::StatusResponse;
using example::StreamService;

class StreamClient
{
 public:
	StreamClient(std::shared_ptr<Channel> channel)
		: stub_(StreamService::NewStub(channel))
	{
	}

	// 调用服务器端接收点云的RPC方法
	void SendPointCloud(const std::string& filename)
	{
		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

		// 创建一个PLYReader对象
		pcl::PLYReader reader;
		// 使用reader从文件中读取点云数据到cloud
		if (reader.read(filename, *cloud) == -1)
		{
			PCL_ERROR("Couldn't read file\n");
			return;
		}

		ClientContext context;
		PointCloud grpcCloud;
		for (const auto& point : *cloud)
		{
			Point* grpcPoint = grpcCloud.add_points();
			grpcPoint->set_x(point.x);
			grpcPoint->set_y(point.y);
			grpcPoint->set_z(point.z);
		}

		StatusResponse response;
		Status status = stub_->SendPointCloud(&context, grpcCloud, &response);
		if (status.ok())
		{
			std::cout << "PointCloud sent successfully. Server says: " << response.message() << std::endl;
		}
		else
		{
			std::cerr << "Failed to send PointCloud: " << status.error_message() << std::endl;
		}
	}

 private:
	std::unique_ptr<StreamService::Stub> stub_;
};

int main(int argc, char** argv)
{
	if (argc != 2)
	{
		std::cerr << "Usage: " << argv[0] << " <pcd file>" << std::endl;
		return -1;
	}

	grpc::ChannelArguments channelArgs;
	// 设置发送消息的最大大小为1G
	channelArgs.SetMaxSendMessageSize(1000 * 1024 * 1024);

	auto channel = grpc::CreateCustomChannel("localhost:50051", grpc::InsecureChannelCredentials(), channelArgs);

	StreamClient client(channel);
	client.SendPointCloud(argv[1]);

	return 0;
}
